package com.yuandian.management.service.impl;

import com.yuandian.api.management.entity.*;
import com.yuandian.bpm.admin.api.entity.SysDictItem;
import com.yuandian.bpm.admin.api.feign.RemoteDictService;
import com.yuandian.bpm.admin.api.feign.RemoteParamService;
import com.yuandian.bpm.common.core.constant.SecurityConstants;
import com.yuandian.management.mapper.FlowAlarmConfMapper;
import com.yuandian.management.service.FlowAlarmConfService;
import com.yuandian.management.vo.flow.alarm.AlarmConfigEntity;
import com.yuandian.management.vo.flow.alarm.AlarmHotConfig;
import com.yuandian.management.vo.flow.alarm.AlarmInfo;
import com.yuandian.management.vo.flow.alarm.ConfAlarmIndicatorCode;
import org.jsoup.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author lijunhang
 * @date 2023年06月05日 13:46
 * @description 实时流告警配置
 */
@Service
public class FlowAlarmConfServiceImpl implements FlowAlarmConfService {

	@Autowired
	private RemoteDictService remoteDictService;

	@Autowired
	private RemoteParamService remoteParamService;

	@Autowired
	private FlowAlarmConfMapper flowAlarmConfMapper;
	/**
	 * 获取实时流告警配置
	 * @return
	 */
	@Override
	public AlarmHotConfig getAlarmConfigEntityConfig() {
		AlarmHotConfig alarmHotConfig=new AlarmHotConfig();
		AlarmConfigEntity alarmConfigEntity=new AlarmConfigEntity();
		//构造参数
		List<SysDictItem> sysAlarmObjType = remoteDictService.getDictByType("sys_alarm_obj_type").getData();
		List<SysDictItem> sysAlarmThresholdLevel=remoteDictService.getDictByType("sys_alarm_threshold_level").getData();

		sysAlarmObjType.forEach(sysDictItem -> {
			alarmConfigEntity.getAlarmObjectConfig().put(Integer.parseInt(sysDictItem.getItemValue()),
					sysDictItem.getLabel());
		});
		sysAlarmThresholdLevel.forEach(sysDictItem -> {
			alarmConfigEntity.getAlarmLevelConfig().put(Integer.parseInt(sysDictItem.getItemValue()),
					sysDictItem.getLabel());

			alarmConfigEntity.getSysDictDataMap().put("sys_alarm_threshold_level"+"@"+sysDictItem.getItemValue(),sysDictItem);
		});

		//查询业务配置
		List<ConfBusiness> businessList = flowAlarmConfMapper.getBusinessList();
		businessList.forEach(confBusiness -> {
			alarmConfigEntity.getBusinessConfig().put(confBusiness.getId(),confBusiness);
		});

		//查询步骤配置
		List<ConfStep> stepList=flowAlarmConfMapper.getStepList();
		stepList.forEach(confStep -> {
			alarmConfigEntity.getProcessConfig().put(confStep.getId(),confStep);
		});


		//查询告警指标配置
		List<ConfAlarmIndicators> confAlarmIndicators=flowAlarmConfMapper.getConfAlarmIndicatorsList();
		confAlarmIndicators.forEach(indicators ->{
			alarmConfigEntity.getAlarmIndicatorConfig().put(indicators.getId(),indicators);
		});

		//查询告警指标编码配置
		List<ConfAlarmIndicatorCode> confAlarmIndicatorCodes=flowAlarmConfMapper.getConfAlarmIndicatorCodeList();
		confAlarmIndicatorCodes.forEach(confAlarmIndicatorCode -> {
			alarmConfigEntity.getAlarmIndicatorCodeConfig().put(confAlarmIndicatorCode.getId(),confAlarmIndicatorCode);
		});



		//查询指标单位
		List<SysDictItem> indicatorsType = remoteDictService.getDictByType("indicators_type").getData();
		indicatorsType.forEach(object->{
			alarmConfigEntity.getAlarmIndicatorUnitConfig().put(Integer.parseInt(object.getItemValue()),object.getLabel());
		});

		//查询告警主表配置
		alarmConfigEntity.setAlarmMainList(flowAlarmConfMapper.getAlarmList());

		//查询告警模板配置
		List<ConfAlarmTemplate> confAlarmTemplates=flowAlarmConfMapper.getConfAlarmTemplateList();
		confAlarmTemplates.forEach(object->{
			alarmConfigEntity.getAlarmTemplateConfig().put(object.getId(),object);
		});

		//获取告警阈值配置
		List<ConfAlarmThreshold> confAlarmThresholds=flowAlarmConfMapper.getConfAlarmThresholdList();
		confAlarmThresholds.forEach(object->{
			List<ConfAlarmThreshold> alarmThresholdList = alarmConfigEntity.getAlarmThresholdConfig()
					.computeIfAbsent(object.getAlarmId(), l -> new ArrayList<>());
			alarmThresholdList.add(object);
		});

		//查询告警维度
		List<ConfAlarmDimension> confAlarmDimensions=flowAlarmConfMapper.getConfAlarmDimensionList();
		confAlarmDimensions.forEach(object->{
			Map<String, List<Integer>> subMap = alarmConfigEntity.getAlarmDimensionConfig()
					.computeIfAbsent(object.getAlarmId(), m -> new HashMap<>());
			List<Integer> dataIdList = subMap.computeIfAbsent(object.getType(), l -> new ArrayList<>());
			dataIdList.add(object.getDataId());
		});

		/**
		 * 组装告警配置
		 */
		List<ConfAlarm> confAlarms=flowAlarmConfMapper.getAlarmList();
		confAlarms.forEach(confAlarm -> {
			// 告警id
			Integer alarmId = confAlarm.getId();



			AlarmInfo alarmInfo = new AlarmInfo();
			alarmInfo.setAlarm(confAlarm);
			// 设置告警阈值列表
			alarmInfo.setAlarmThresholdList(alarmConfigEntity.getAlarmThresholdConfig().get(alarmId));

			// 组装维度字符串
			Map<String, List<Integer>> dimensionMap = alarmConfigEntity.getAlarmDimensionConfig().get(alarmId);
			List<String> dimensionList = new ArrayList<>();
			if (!CollectionUtils.isEmpty(dimensionMap)) {
				List<Integer> systemDimensionList = dimensionMap.get("SYSTEM");
				List<Integer> businessDimensionList = dimensionMap.get("BUSINESS");
				List<Integer> segmentDimensionList = dimensionMap.get("SEGMENT");
				List<Integer> stepDimensionList = dimensionMap.get("STEP");
				if (!CollectionUtils.isEmpty(systemDimensionList)) {
					for (Integer systemId : systemDimensionList) {
						if (!CollectionUtils.isEmpty(businessDimensionList)) {
							for (Integer businessId : businessDimensionList) {
								ConfBusiness business = alarmConfigEntity.getBusinessConfig().get(businessId);
								if (business != null) {
									if (!CollectionUtils.isEmpty(stepDimensionList)) {
										for (Integer stepId : stepDimensionList) {
											ConfStep step = alarmConfigEntity.getProcessConfig().get(stepId);
											if (step != null) {
												dimensionList.add(systemId + "@" + business.getBusinessCode()
														+ "@" + step.getStepCode());
											}
										}
									} else {
										dimensionList.add(systemId + "@" + business.getBusinessCode());
									}
								}
							}
						} else if (!CollectionUtils.isEmpty(segmentDimensionList)) {
							for (Integer segmentId : segmentDimensionList) {
								dimensionList.add(systemId + "@" + segmentId);
							}
						} else {
							dimensionList.add(String.valueOf(systemId));
						}
					}
				} else {
					dimensionList.add("DEFAULT");
				}
			} else {
				dimensionList.add("DEFAULT");
			}
			if (confAlarm.getAlarmIndicatorId() != null&&confAlarm.getAlarmObjId() != null) {
				Map<Integer, Map<String, AlarmInfo>> alarmObjMap = alarmConfigEntity.getAlarmInfoConfig()
						.computeIfAbsent(confAlarm.getAlarmIndicatorId(), m -> new HashMap<>());
				Map<String, AlarmInfo> richDimensionMap = alarmObjMap
						.computeIfAbsent(confAlarm.getAlarmObjId(), m -> new HashMap<>());
				for (String dimension : dimensionList) {
					richDimensionMap.put(dimension, alarmInfo);
				}
			}
		});


		//获取告警维度配置
		alarmConfigEntity.setAlarmsDimensionList(flowAlarmConfMapper.getConfAlarmDimensionList());

		alarmConfigEntity.getAlarmsDimensionList().forEach(confAlarmDimension -> {
			Integer alarmId = confAlarmDimension.getAlarmId();
			if (alarmId != null) {
				String type = confAlarmDimension.getType();
				if (type != null && AlarmEnum.DimensionTypeEnum.getEnumByValue(type) != null) {
					Map<String, List<ConfAlarmDimension>> secondMap =
							alarmConfigEntity.getAlarmsDimensionMap().computeIfAbsent(alarmId.toString(), k -> new HashMap<>());
					List<ConfAlarmDimension> dimensionList = secondMap.computeIfAbsent(type, k -> new ArrayList<>());
					dimensionList.add(confAlarmDimension);
				}
			}
		});


		/*
		  获取告警阀值List集合
		 */
		alarmConfigEntity.setAlarmThresholdList(confAlarmThresholds);

		/*
		 * 告警阀值Map集合,<告警配置Id,List<AlarmThreshold>>
		 */
		confAlarmThresholds.forEach(threshold -> {
			if (threshold != null) {
				//增加阀值级别名称
				AlarmLevel alarmLevel = threshold.getAlarmLevel();
				if (alarmLevel != null) {
					Integer levelId = alarmLevel.getId();
					if (levelId != null) {
						SysDictItem sysDictData = alarmConfigEntity.getSysDictDataMap().get("sys_alarm_threshold_level" + "@" + levelId.toString());

						if (sysDictData != null) {
							alarmLevel.setName(sysDictData.getLabel());
						}
					}
				}
				Integer alarmId = threshold.getAlarmId();
				if (alarmId != null) {
					List<ConfAlarmThreshold> alarmThresholds = alarmConfigEntity.getAlarmThresholdMap().get(alarmId.toString());
					if (alarmThresholds == null) {
						alarmThresholds = new ArrayList<>();
						alarmConfigEntity.getAlarmThresholdMap().put(alarmId.toString(), alarmThresholds);
					}
					alarmThresholds.add(threshold);
				}
			}
		});

		/**
		 * 获取所有告警配置List集合
		 */
		alarmConfigEntity.setAlarmConfigList(flowAlarmConfMapper.getAlarmList());


		/**
		 * 获取有效告警配置List集合
		 */
		alarmConfigEntity.getAlarmConfigList().forEach(config -> {
			if ("2".equals(config.getType().toString())) {
				Integer configId = config.getId();
				//告警配置增加维度配置
				if (alarmConfigEntity.getAlarmsDimensionMap() != null) {
					Map<String, List<ConfAlarmDimension>> tDimensionMap = alarmConfigEntity.getAlarmsDimensionMap().get(configId.toString());
					if (tDimensionMap != null) {
						int sequence = calculateSequence(tDimensionMap);
						config.setSequence(sequence);
						config.setAlarmsDimensionMap(tDimensionMap);
					}
				}
				//告警配置增加告警模板配置
				if (config.getAlarmTemplate() != null) {
					ConfAlarmTemplate alarmTemplate =  alarmConfigEntity.getAlarmTemplateConfig().get(config.getAlarmTemplate().getId());
					config.setAlarmTemplate(alarmTemplate);
				}
				//告警配置增加阀值
				if (alarmConfigEntity.getAlarmThresholdMap() != null) {
					List<ConfAlarmThreshold> alarmThresholds =alarmConfigEntity.getAlarmThresholdMap().get(configId.toString());
					if (alarmThresholds != null && alarmThresholds.size() > 0) {
						config.setThresholds(alarmThresholds);
					}
				}
				alarmConfigEntity.getValidAlarmConfigList().add(config);
			}
		});


		/**
		 * 获取告警配置Map集合
		 */
		alarmConfigEntity.getValidAlarmConfigList().forEach(alarmConfig -> {
			if (alarmConfig != null) {
				Integer indicatorId = alarmConfig.getAlarmIndicatorId();
				if (indicatorId != null) {
					List<ConfAlarm> alarmConfigs = alarmConfigEntity.getAlarmConfigMap().computeIfAbsent(indicatorId.toString(), k -> new ArrayList<>());
					alarmConfigs.add(alarmConfig);
				}
			}
			//按照告警配置的比较次序进行排序(从大往小排序)
			if (alarmConfigEntity.getAlarmConfigMap() != null) {
				for (Map.Entry<String, List<ConfAlarm>> entrySet : alarmConfigEntity.getAlarmConfigMap().entrySet()) {
					List<ConfAlarm> list = entrySet.getValue();
					if (list != null && list.size() > 0) {
						Collections.sort(list, new Comparator<ConfAlarm>() {
							@Override
							public int compare(ConfAlarm config1, ConfAlarm config2) {
								if (config1.getSequence() > config2.getSequence()) {
									return -1;
								} else if (config1.getSequence() < config2.getSequence()) {
									return 1;
								}
								return 0;
							}
						});
					}
				}
			}
		});


		/*
		 * 获取告警指标List集合
		 */
		alarmConfigEntity.setAlarmIndicatorList(flowAlarmConfMapper.getConfAlarmIndicatorsList());


		/**
		 * 获取有效的自定义指标
		 */
		alarmConfigEntity.getAlarmIndicatorList().forEach(indicator->{
			if (indicator != null) {
				// 有效的自定义告警
				if (2 == indicator.getType()) {
					Integer indicatorId = indicator.getId();
					List<ConfAlarm> alarmConfigs = alarmConfigEntity.getAlarmConfigMap().get(indicatorId.toString());
					if (alarmConfigs != null && alarmConfigs.size() > 0) {
						// 指标增加告警配置
						indicator.setAlarmConfigList(alarmConfigs);
					}
					Integer particleId = indicator.getParticleId();
					if (particleId != null && AlarmEnum.ParticleEnum.getEnumByValue(particleId.toString()) != null) {
						//指标增加颗粒度枚举
						indicator.setParticleEnum(AlarmEnum.ParticleEnum.getEnumByValue(particleId.toString()));
					}
					Integer objId = indicator.getObjId();
					if (objId != null && AlarmEnum.IndicatorObjEnum.getEnumByValue(objId.toString()) != null) {
						//指标增加指标对象枚举
						indicator.setIndicatorObjEnum(AlarmEnum.IndicatorObjEnum.getEnumByValue(objId.toString()));
					}
					alarmConfigEntity.getCustomIndicatorList().add(indicator);
				}
			}
		});


		/**
		 * 获取告警指标Map集合
		 */
		alarmConfigEntity.getCustomIndicatorList().forEach(indicator -> {
			if(alarmConfigEntity.getBusiStatusAlarmIndicatorName().contains(indicator.getName() + "|")) {
				alarmConfigEntity.getBusiStatusIndicatorList().add(indicator);

			} else {
				Integer particleId = indicator.getParticleId();
				Integer objId = indicator.getObjId();
				if (particleId != null && objId != null) {
					String key = particleId + "@" + objId;
					List<ConfAlarmIndicators> list = alarmConfigEntity.getCustomIndicatorMap().computeIfAbsent(key, k -> new ArrayList<>());
					list.add(indicator);
				}
			}
		});

		/**
		 * 运维工作台获取'高频、经常、低频'业务的阈值
		 */
		String highValueStr = remoteParamService.getByKey("sys.ops.highValue", SecurityConstants.FROM_IN).getData();
		String oftenValueStr = remoteParamService.getByKey("sys.ops.oftenValue", SecurityConstants.FROM_IN).getData();
		String lowValueStr = remoteParamService.getByKey("sys.ops.lowValue", SecurityConstants.FROM_IN).getData();
		String highFailAlarmValueStr = remoteParamService.getByKey("sys.ops.highFailAlarmValue", SecurityConstants.FROM_IN).getData();

		if (StringUtil.isNumeric(highValueStr)) { alarmConfigEntity.setHighValue(Integer.parseInt(highValueStr)); }
		if (StringUtil.isNumeric(oftenValueStr)) { alarmConfigEntity.setOftenValue(Integer.parseInt(oftenValueStr)); }
		if (StringUtil.isNumeric(lowValueStr)) { alarmConfigEntity.setLowValue(Integer.parseInt(lowValueStr)); }
		if (StringUtil.isNumeric(highFailAlarmValueStr)) { alarmConfigEntity.setHighFailAlarmValue(Integer.parseInt(highFailAlarmValueStr)); }

		// 运维工作台-记录共用接口业务服务资源

		alarmConfigEntity.setPublicResourceCodeSet(flowAlarmConfMapper.getPublicResourceCodeSet());


		alarmHotConfig.setAlarmConfigEntity(alarmConfigEntity);
		return alarmHotConfig;
	}


	/**
	 * 计算告警配置的比较次序
	 * 用于同一个指标下不同告警配置的比较次序
	 * 计算规则：
	 * 当系统、网端、业务为“所有”时，dataId值为0,其次序最低为0.
	 * 当不是“所有”时，一个不是“所有”的选项则次序增加1
	 * @return
	 */
	private static int calculateSequence(Map<String, List<ConfAlarmDimension>> dimensionMap) {
		if (dimensionMap == null) {
			return 0;
		}
		int count = 0;
		for (Map.Entry<String, List<ConfAlarmDimension>> entrySet : dimensionMap.entrySet()) {
			List<ConfAlarmDimension> list = entrySet.getValue();
			if (list != null && list.size() > 0) {
				for (ConfAlarmDimension dimension : list) {
					Integer dataId = dimension.getDataId();
					if (dataId != null && !dataId.equals(0)) {
						count++;
					}
				}
			}
		}
		return count;
	}
}
